home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-02 | 7.5 KB | 256 lines | [TEXT/YERK] |
- \ New ColorGraphPort support
- \ 6.18.87 rfl
- \ 9.21.88 rfl don't lock during calcrange
- \ 1.11.89 rfl redone for multiple instances
- \ 1.28.89 rfl helped getpalette in cwind
- \ 2.23.89 rfl uget in rgbColor
- \ 6.1.89 rfl adjustGray: pixmap now saturates to 0 or $ ffff
- \ 9.5.89 rfl modified for generality and 16 bit images
- \ 3.6.92 rfl changed 0 to 'lo $ 101 *' in adjustlimits: pixmap
- \ which helps things if lo=hi
- \ 6.16.92 rfl moved forecolor, backcolor out of class; changed lo $ 101 * back
- \ to 0.
- \ 5.10.94 rfl changed default cwindow to pmcourteous
-
- \ : makeEven dup 1 and IF 1+ THEN ;
-
- \ given a number, calculate the power of 2 to give that number
- : p2 ( n -- powerOf2) 100 0 DO 2/ dup 0= IF drop i leave THEN LOOP ;
-
- \ ( b -- bool ) make a Forth boolean into a Toolbox boolean
- : Bool 8 << makeInt ;
-
- : foreColor ( ind --) makeint call PmForeColor ;
- : backColor ( ind --) makeint call PmBackColor ;
-
- \ standard data structure for colors
- :CLASS rgbColor <super object
-
- int red
- int green
- int blue
-
- :M put: put: blue put: green put: red ;M
- :M get: uget: red uget: green uget: blue ;M
-
- ;CLASS
-
- \ general purpose global color records
- rgbColor inColor
- rgbColor outColor
-
-
- 0 constant pmCourteous
- 1 constant pmDithered
- 2 constant pmTolerant
- 4 constant pmAnimated
- 8 constant pmExplicit
-
- \ order of use: new, putwindow, fillgray, openwindow, set, activate?
- :CLASS palette <super handle
-
- int size
- var myWindow
- int myUsage
- int tolerance
-
- ( wind --)
- :M putWindow: +base put: mywindow ;M
- ( usage --)
- :M usage: put: myUsage ;M
- :M tolerance: put: tolerance ;M
- :M putSize: put: size ;M
-
- ( #colors --)
- :M new: put: size 0 int: size 0 int: myUsage w 0 call NewPalette put: self ;M
- :M dispose: get: self call DisposePalette 0 m! ;M
-
- :M activate: get: myWindow call ActivatePalette ;M
- \ might change true to false for no updates on color environ change
- :M set: get: myWindow get: self true bool call SetPalette ;M
-
- :M getColor: { ind -- }
- get: self ind makeint abs: outColor call GetEntryColor ;M
- :M setColor: { ind -- }
- get: self ind makeint abs: inColor call SetEntryColor ;M
-
- \ fills the color table evenly rgb - as IMAC says, do we want black,white
- \ to be the first two colors? i don't think so here, but we do it anyway
- :M fillGray: get: size 2
- DO $ 10000 i 1- get: size */ i+ 1- dup dup put: inColor i setColor: self LOOP
- $ ffff dup dup put: incolor 1 setcolor: self
- 0 dup dup put: incolor 0 setcolor: self
- activate: self ;M
-
- :M putCTable: { ctable - } get: ctable m@ int: myUsage w 0
- call CTab2Palette ;M
-
- ;CLASS
-
- \ instantiate a global palette for operations
- palette thePalette
-
- \ general purpose colortable <-> palette operations
- ( srcTableHndl dstPaletteHndl use tol -- )
- : cTab2Palette pack call CTab2Palette ;
- ( srcPaletteHndl dstCTabHndl -- )
- : Palette2CTab call Palette2CTab ;
-
- :CLASS ColorTable <super handle
-
- \ fill with an existing colorTable
- :M fill: { myCTable -- } lock: self lock: myCTable
- ptr: myCTable 8+ ptr: self 8+ size: self 8 -
- cmove unlock: myCTable unlock: self ;M
-
- :M seed: 0 call getCTSeed m@ >ptr ! ;M
-
- ( #colors --)
- :M new: dup 8* 8+ new: super 1- ptr: self 6 + w! seed: self ;M
- :M dispose: m@ call disposCTable 0 m! ;M
-
- :M getPalette: { pal -- } get: pal m@ Palette2CTab ;M
- :M toPalette: { pal -- } m@ get: pal 0 0 CTab2Palette ;M
-
- ( -- size )
- :M ctsize: ptr: self 6 + w@ 1+ ;M
-
- ( #colors -- ) \ useful to change an existing colorTable's size
- :M init: dup 8* 8+ setSize: self
- 1- ptr: self 6 + w! seed: self ;M
-
- :M fillGray: { \ nextAddr vals -- } lock: self
- ptr: self 8+ -> nextAddr ctSize: self 0
- DO i nextAddr w! 2 ++> nextAddr $ 10000 i ctsize: self */ i+ -> vals 3 0
- DO vals nextAddr w! 2 ++> nextAddr LOOP
- LOOP unlock: self ;M
-
- ;CLASS
-
- \ instantiate a global colortable for operations
- colorTable theCTable
-
-
- \ : CALCMB { X1 X0 -- B M } 256. X1 X0 - >FLOAT F/
- \ FDUP X0 >FLOAT F* FNEGATE SWAP ;
- \
- \ ( max min -- M*100 B*100 )
- \ : GETMB CALCMB 100. F* ROUND FLOAT> SWAP
- \ 100. F* ROUND FLOAT> ;
-
- ( max min -- M*100 B*100 )
- : GETMB { X1 X0 -- M*100 B*100 } 256 100 X1 X0 - */
- DUP X0 * NEGATE ;
-
- :CLASS PixMap <super handle
-
- colorTable myCTab
- rect destRect
- int mask \ $ffff for inverted images, 0 normal
- var pixImage \ pointer to the image for this pixMap
-
- \ **************************
- \ INITIALIZE METHODS
- \ **************************
-
- \ image black-on-white or white-on-black
- :M negate: $ FFFF put: mask ;M
- :M normal: clear: mask ;M
- :M invert: $ FFFF get: mask xor put: mask ;M
-
- \ changes number bits/pixel
- :M putBits/pixel: m@ >ptr 32 + w! ;M
- :M getBits/pixel: m@ >ptr 32 + w@ ;M
-
- \ boundRect is the rectangle bordering the image
- :M putBounds: ( l t r b -- ) m@ >ptr 6 + put: rect ;M
- :M getBounds: ( -- l t r b ) m@ >ptr 6 + get: rect ;M
- :M putBoundsRect: ( rect --) m@ >ptr 6 + 8 cmove ;M
-
- \ destRect is the destination rectangle that the contents of boundsrect will be stuffed
- :M putDest: put: destRect ;M
- :M getDest: get: destRect ;M
-
- \ should I lock these first?
- ( addr --)
- :M putImage: +base m@ >ptr ! ;M
- ( rowbytes --) \ add $ 8000 for pixel image
- :M putRowBytes: ( makeEven) $ 8000 + m@ >ptr 4+ w! ;M
-
- \ **************************
- \ CREATION AND DISPOSAL METHODS
- \ **************************
-
- ( image --) \ get a new pixMap structure from Toolkit
- :M new: put: pixImage \ store the image for this pixMap
- 0 call NewPixMap m! \ get handle to pixmap
- ptr: self 42 + @ put: myCTab \ get handle to colortable
- #colors: [ obj: pixImage ] dup \ get number of colors in image
- init: myCTab \ initialize the colorTable
- p2 putBits/pixel: self
- fillgray: myCTab ;M
-
- :M dispose: m@ call DisposPixMap 0 m! ;M
-
- \ **************************
- \ MANIPULATION METHODS
- \ **************************
-
- ( ctable --)
- :M putCTable: m@ >ptr 42 + ! ;M
- \ puts handle into global colortable for manipulation as an object
- :M getCTable: m@ >ptr 42 + @ put: theCTable ;M
-
- ( addr rowBytes b/p l t r b --)
- :M set: putBounds: self
- putBits/pixel: self putRowBytes: self putImage: self ;M
-
- \ creates new pixmap based on image to display
- :M Prep: { pix -- } dispose: self \ get rid of old pixmap
- pix new: self \ make new one
- ptr: pix rowBytes: pix \ set up parameters
- bits/pixel: pix 8 min getRect: pix
- set: self
- getBounds: self putDest: self ;M
-
- \ takes the pixMap and copies it into the window on the stack
- \ using parameters set by prep:
- :M Copy: { wind -- } ptr: self +base wind 2+ @ >ptr +base
- ptr: self 6 + +base abs: destRect w 0 wind 24 + @ \ use vsrgn of wind
- call copyBits ;M
-
- ( destPixMap --) \ copies this pixMap into destPixMap on stack
- :M =: @ m@ swap call copyPixMap ;M
-
- \ **************************
- \ COLORTABLE ADJUSTMENTS
- \ **************************
-
- \ given the range of values in an image, this will attempt to
- \ linearly scale the contents of the image to the number of colors
- \ in the pixMaps color table.
-
- :M adjustLimits: { hi lo \ nextAddr vals M B -- }
- getcTable: self lock: theCTable \ put pixMap's ctab into global obj
- ptr: theCTable 8+ -> nextAddr \ set up pointer to entry
- hi lo getMB -> B -> M \ calc limits of values
- 1 getBits/pixel: self << 0 \ get #colors DO limit
- DO i nextAddr w! 2 ++> nextAddr \ begin filling ctable
- i lo <=
- IF 0 \ force to zero
- ELSE i hi >=
- IF $ ffff
- ELSE $ ffff $ 10000 M i * B + $ 6400 */ i+ min 0 max
- THEN
- THEN get: mask xor -> vals 3 0
- DO vals nextAddr w! 2 ++> nextAddr LOOP
- LOOP unlock: theCTable ;M \ done, so unlock ctable
-
- :M adjustGray: range: [ obj: pixImage ] drop adjustLimits: self ;M
-
- \ just fill the ctable from 0-255 grayscale
- :M fillgray: fillGray: myCtab ;M
-
- ;CLASS
-
-